﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "SnapFilterDlg.h"
#include "IDock.h"
#include "GbmpNew.h"
#include "ICategory.h"
#include "IUiManager.h"
#include "IMainWindow.h"
#include "UniIdentity.h"
#include "IDockManager.h"
#include "ISnapContext.h"
#include "ISnapSettings.h"
#include "ICategoryLibrary.h"
#include "IPickPointAction.h"
#include "IUiDocumentViewManager.h"
#include "IPickPointActionConfig.h"

#include "qevent.h"
#include "QTreeWidget.h"
#include "BaseTreeDlg.h"
#include "PickSnapCommandIds.h"
#include "CmdSnapModuleEntry.h"
///#include "PickFilterDialogEventHandlers.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace Sample;

#pragma region 初始化
SnapFilterDlg::SnapFilterDlg(QWidget *parent)
    : BaseTreeDlg(parent)
{
    InitQTree();
    SetSnapMethod(SnapMethod::IPickPointAction);
}

SnapFilterDlg::~SnapFilterDlg(void){}
#pragma endregion 初始化

#pragma region 和GDMP GUI接口相关的初始化和单例获取
SnapFilterDlg* SnapFilterDlg::Create()
{
    if (SnapFilterDlg* pSnapDlg = Get())
    {
        return pSnapDlg;
    }
    IUiManager *pUiManager = IUiManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiManager, L"pUiManager为空",L"GDMP",L"2023-12-30");

    IDockManager * pDockManager = pUiManager->GetDockManager();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDockManager, L"pDockManager为空",L"GDMP",L"2023-12-30");

    IUiDocumentViewManager * pUiDocViewMgr = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocViewMgr, L"pUiDocViewMgr为空",L"GDMP",L"2023-12-30");

    OwnerPtr<IDock> opDock = pDockManager->CreateDock(ID_DOCK_SNAP_FILTER, GBMP_TR(L"捕捉过滤"));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opDock, L"opDock为空",L"GDMP",L"2023-12-30");
    
    OwnerPtr<SnapFilterDlg> opSnapDlg = NEW_AS_OWNER_PTR(SnapFilterDlg);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSnapDlg, L"opSnapDlg为空",L"GDMP",L"2023-12-30");
    opSnapDlg->setMinimumWidth(200);
    opDock->SetWidget(TransferOwnership(opSnapDlg));

    pDockManager->AddDock(TransferOwnership(opDock), DockArea::Right, DockOrientation::Vertical);

    return Get();
}

void Sample::SnapFilterDlg::ShowDock()
{
    IDock* pDock = GetDock(ID_DOCK_SNAP_FILTER);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDock, L"pDock为空",L"GDMP",L"2023-12-30");
    pDock->Show();
}

void Sample::SnapFilterDlg::HideDock()
{
    IDock* pDock = GetDock(ID_DOCK_SNAP_FILTER);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDock, L"pDock为空",L"GDMP",L"2023-12-30");
    pDock->Hide();
}

SnapFilterDlg * SnapFilterDlg::Get()
{
    IDock* pDock = GetDock(ID_DOCK_SNAP_FILTER);
    if (!pDock)
    {
        return nullptr;
    }

    SnapFilterDlg* dlg = dynamic_cast<SnapFilterDlg*>(pDock->GetWidget());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(dlg, L"dlg为空",L"GDMP",L"2023-12-30");
    return dlg;
}
#pragma endregion 和GDMP GUI接口相关的初始化和单例获取

#pragma region 和捕捉相关的逻辑
void SnapFilterDlg::InitQTree()
{
    m_pQTreeWidget->clear();
    m_pQTreeWidget->setSortingEnabled(false);

    std::map<std::wstring, std::function<void(ISnapContext*, bool)>> snapContextMap = {
        {L"SetRemoveDuplicateRemoteSnaps", [](ISnapContext* pSnapContext, bool flag)->void {pSnapContext->SetRemoveDuplicateRemoteSnaps(flag); }},
        {L"SetIsDirectionDeterminedByModelView", [](ISnapContext* pSnapContext, bool flag)->void {pSnapContext->SetIsDirectionDeterminedByModelView(flag); }}
    };
    m_snapContextMap.insert(snapContextMap.begin(), snapContextMap.end());

    std::map<std::wstring, std::function<void(ISnapSettings*, bool)>> snapSettingsMap = {
        { L"SetIsSnapOff", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetIsSnapOff(flag); } },
        { L"SetIsRemoteSnapOff", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetIsRemoteSnapOff(flag); } },
        { L"SetCanSnapMiddlePoint", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapMiddlePoint(flag); } },
        { L"SetCanCentersSnap", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanCentersSnap(flag); } },
        { L"SetCanSnapCenter", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapCenter(flag); } },
        { L"SetCanSnapNearest", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapNearest(flag); } },
        { L"SetCanSnapQuadrants", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapQuadrants(flag); } },
        { L"SetCanSnapTangent", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapTangent(flag); } },
        { L"SetCanSnapCollineation", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapCollineation(flag); } },
        { L"SetCanParallelSnap", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanParallelSnap(flag); } },
        { L"SetCanPerpendicularSnap", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanPerpendicularSnap(flag); } },
        { L"SetCanSnapPerpendicularPoint", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapPerpendicularPoint(flag); } },
        { L"SetCanExtensionSnap", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanExtensionSnap(flag); } },
        { L"SetCanSnapOriginalLine", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapOriginalLine(flag); } },
        { L"SetCanSnapIntersectionPoint", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapIntersectionPoint(flag); } },
        { L"SetCanSnapLength", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapLength(flag); } },
        { L"SetCanSnapAngle", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapAngle(flag); } },
        { L"SetCanSnapHorizontalVerticalLine", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapHorizontalVerticalLine(flag); } },
        { L"SetIsForceHorizontalOrVertical", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetIsForceHorizontalOrVertical(flag); } },
        { L"SetCanSnapEndPoint", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapEndPoint(flag); } },
        { L"SetCanSnapCustomPoint", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnapCustomPoint(flag); } },
        { L"SetCanSnap3dPoint", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnap3dPoint(flag); } },
        { L"SetCanSnap3DExtension", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnap3DExtension(flag); } },
        { L"SetCanSnap3DParallel", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnap3DParallel(flag); } },
        { L"SetCanSnap3DAxialDirectionLine", [](ISnapSettings* pSnapSettings, bool flag)->void { pSnapSettings->SetCanSnap3DAxialDirectionLine(flag); } },
    };
    m_snapSettingsMap.insert(snapSettingsMap.begin(), snapSettingsMap.end());

    QTreeWidgetItem *topLevelItem = NEW_AS_QT(QTreeWidgetItem, m_pQTreeWidget);
    DBG_WARN_AND_RETURN_VOID_UNLESS(topLevelItem, L"topLevelItem为空",L"GDMP",L"2023-12-30");
    topLevelItem->setText(0, QString::fromStdWString(GBMP_TR(L"捕捉过滤")));

    {
        m_snapContextNodeGroup = NEW_AS_QT(QTreeWidgetItem, topLevelItem);
        m_snapContextNodeGroup->setCheckState(0, Qt::Checked);
        m_snapContextNodeGroup->setText(0, QString::fromStdWString(GBMP_TR(L"ISnapContext")));

        for (auto itor : m_snapContextMap)
        {
            QTreeWidgetItem *curItem = NEW_AS_QT(QTreeWidgetItem, m_snapContextNodeGroup);
            DBG_WARN_AND_RETURN_VOID_UNLESS(curItem, L"curItem为空",L"GDMP",L"2023-12-30");
            curItem->setCheckState(0, Qt::Checked);
            curItem->setText(0, QString::fromStdWString(GBMP_TR(itor.first)));
            m_snapContextNodeGroup->addChild(curItem);
        }
    }

    {
        m_snapSettingsNodeGroup = NEW_AS_QT(QTreeWidgetItem, topLevelItem);
        m_snapSettingsNodeGroup->setCheckState(0, Qt::Checked);
        m_snapSettingsNodeGroup->setText(0, QString::fromStdWString(GBMP_TR(L"ISnapSettings")));

        for (auto itor : m_snapSettingsMap)
        {
            QTreeWidgetItem *curItem = NEW_AS_QT(QTreeWidgetItem, m_snapSettingsNodeGroup);
            DBG_WARN_AND_RETURN_VOID_UNLESS(curItem, L"curItem为空",L"GDMP",L"2023-12-30");
            curItem->setCheckState(0, Qt::Checked);
            curItem->setText(0, QString::fromStdWString(GBMP_TR(itor.first)));
            m_snapSettingsNodeGroup->addChild(curItem);
        }
    }

    m_pQTreeWidget->expandAll();
}

void SnapFilterDlg::SetSnapContext(gcmp::ISnapContext* pSnapContext)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pSnapContext, L"pSnapContext为空",L"GDMP",L"2023-12-30");
    for (int i = 0; i < m_snapContextNodeGroup->childCount(); i++)
    {
        QTreeWidgetItem* item = m_snapContextNodeGroup->child(i);
        DBG_WARN_AND_RETURN_VOID_UNLESS(item, L"item为空",L"GDMP",L"2023-12-30");
        std::wstring itemText = item->text(0).toStdWString();
        auto itor = m_snapContextMap.find(itemText);
        if (itor != m_snapContextMap.end())
        {
            DBG_WARN_AND_RETURN_VOID_UNLESS(itor->second, L"itor为空",L"GDMP",L"2023-12-30");
            itor->second(pSnapContext, item->checkState(0) == Qt::Checked);
        }
    }
}

void SnapFilterDlg::SetSnapSettings(gcmp::ISnapSettings* pSnapSettings)
{
    pSnapSettings->DisableAllSnaps();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pSnapSettings, L"pSnapSettings为空",L"GDMP",L"2023-12-30");
    for (int i = 0; i < m_snapSettingsNodeGroup->childCount(); i++)
    {
        QTreeWidgetItem* item = m_snapSettingsNodeGroup->child(i);
        DBG_WARN_AND_RETURN_VOID_UNLESS(item, L"item为空",L"GDMP",L"2023-12-30");
        std::wstring itemText = item->text(0).toStdWString();
        auto itor = m_snapSettingsMap.find(itemText);
        if (itor != m_snapSettingsMap.end())
        {
            DBG_WARN_AND_RETURN_VOID_UNLESS(itor->second, L"itor为空",L"GDMP",L"2023-12-30");
            itor->second(pSnapSettings, item->checkState(0) == Qt::Checked);
        }
    }
}

void Sample::SnapFilterDlg::SetSnapMethod(SnapMethod snapMethod)
{
    if (snapMethod == SnapMethod::Snapper)
    {
        m_snapContextNodeGroup->setHidden(false);
        m_snapSettingsNodeGroup->setHidden(false);

    }
    else if (snapMethod == SnapMethod::IPickPointAction)
    {
        m_snapContextNodeGroup->setHidden(false);
        m_snapSettingsNodeGroup->setHidden(false);
    }
    else
    {
        m_snapContextNodeGroup->setHidden(false);
        m_snapSettingsNodeGroup->setHidden(false);
    }
}

#pragma endregion 和捕捉相关的逻辑

